#pragma once

namespace ManagedVC1
{
	public ref class MotionEstimationProperties
	{
	private:
		unsigned long m_DeltaMVRangeIndex, m_MotionSearchLevel, m_MotionSearchMethod, m_MBModeCost, m_MVCost, m_MVRange;
	public:
		/// <summary>
		/// Delta motion vector (MV) coding specifies the bin sizes used to code delta motion vector distributions in field pictures. 
		/// Larger bins are more efficient at storing wider distributions of delta motion vectors. 
		/// Wide delta MV distributions are typical of videos containing lots of random motion. 
		/// Since clips are very rarely composed of random motion, this feature is most likely to be of use for segment re-encoding.
		///
		/// Field pictures are only used in interlaced video encoding.
		/// 
		/// <list type="table">
		/// <item><term>0</term><description>Off (Default)</description></item>
		/// <item><term>1</term><description>Improves coding efficiency for highly spread-out horizontal delta motion vector distributions.</description></item>
		/// <item><term>2</term><description>Improves coding efficiency for highly spread-out vertical delta motion vector distributions.</description></item>
		/// <item><term>3</term><description>Improves coding efficiency for highly spread-out horizontal and vertical delta motion vector distributions.</description></item>
		/// </list>
		/// </summary>
		property unsigned long DeltaMVRangeIndex
		{
			unsigned long get() { return m_DeltaMVRangeIndex; }
			void set(unsigned long value)
			{
                if (value > 3) throw gcnew System::ArgumentOutOfRangeException("DeltaMVRangeIndex cannot be larger than 3");
				m_DeltaMVRangeIndex = value;
			}
		}

		property unsigned long MotionSearchLevel
		{
			unsigned long get() { return m_MotionSearchLevel; }
			void set(unsigned long value)
			{
				if (value > 4) throw gcnew System::ArgumentOutOfRangeException("MotionSearchLevel cannot be larger than 4");
				m_MotionSearchLevel = value;
			}
		}

		property unsigned long MotionSearchMethod
		{
			unsigned long get() { return m_MotionSearchMethod; }
			void set(unsigned long value)
			{
				if (value > 2) throw gcnew System::ArgumentOutOfRangeException("MotionSearchMethod cannot be larger than 2");
				m_MotionSearchMethod = value;
			}
		}

		property unsigned long MBModeCost
		{
			unsigned long get() { return m_MBModeCost; }
			void set(unsigned long value)
			{
				if (value > 1) throw gcnew System::ArgumentOutOfRangeException("MBModeCost cannot be larger than 1");
				m_MBModeCost = value;
			}
		}

		property unsigned long MVCost
		{
			unsigned long get() { return m_MVCost; }
			void set(unsigned long value)
			{
				if (value > 1) throw gcnew System::ArgumentOutOfRangeException("MVCost cannot be larger than 1");
				m_MVCost = value;
			}
		}

		property unsigned long MVRange
		{
			unsigned long get() { return m_MVRange; }
			void set(unsigned long value)
			{
				if (value > 4) throw gcnew System::ArgumentOutOfRangeException("MVRange cannot be larger than 4");
				m_MVRange = value;
			}
		}
	};
}